package com.starbaba.core.service;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.hibernate.type.Type;

import com.starbaba.core.hibernate.DAOFactory;
import com.starbaba.core.hibernate.HibernateDAO;
import com.starbaba.core.hibernate.Page;
import com.starbaba.core.hibernate.QueryType;
import com.starbaba.core.hibernate.Strategy;
import com.starbaba.core.web.sequence.Sequence;
import com.starbaba.system.logaccess.model.LogAccessVO;
import com.starbaba.system.managelog.model.OperAction;
import com.starbaba.system.managelog.view.ManageLogToStringStyle;


@SuppressWarnings({"serial","rawtypes"})
public class CommonServiceSupport implements Serializable{

	/**
	 * 执行SQL 
	 * @param sql
	 * @param vo
	 * @return
	 *
	 * @Copyright: Copyright (c) 2006
	 * @Company: Revenco Tech Ltd.
	 * @anthor chenminhui<chenminhui@revenco.com>
	 * @since 2014-11-18 下午03:58:17
	 * @version V1.0
	 */
	public int executeSQLUpdate(String sql, Object... values) {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.executeSQLUpdate(sql, values);
	}
	
	/**
	 * 执行HQL
	 * @param hql 
	 * @param values “?”参数数组
	 * @return 执行条数
	 *
	 * @Copyright: Copyright (c) 2006
	 * @Company: Revenco Tech Ltd.
	 * @anthor chenminhui<chenminhui@revenco.com>
	 * @since 2014-11-18 下午03:59:18
	 * @version V1.0
	 */
	public int executeHQLUpdate(String hql, Object... values) {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.executeHQLUpdate(hql, values);
	}
	
	public int executeHQLUpdate(String hql, Map<String,Object> params) {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.executeHQLUpdate(hql, params);
	}
	
	public Object doCreate(Class<?> voClass, Object vo) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.save(vo);
	}
	
	public Object doUpdate(Class<?> voClass, Object vo) throws Exception {
		HibernateDAO  dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.saveOrUpdate(vo);
	}
	
	public void doRemoveByVO(Class<?> voClass, Object vo) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		dao.deleteByVO(vo);
	}

	public void doRemoveByPK(Class<?> voClass, Serializable pk) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		dao.deleteByPK(pk);
	}

	public Object doFindByPk(Class<?> voClass, Serializable pk) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.findByPK(pk);
	}
	
	public List doFindALL(Class<?> voClass) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.findAll();
	}
	

	public Page doQuery(Class<?> voClass, Object params) throws Exception {
		HibernateDAO  dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.query(params);
	}
	
	public Page doQuery(Class<?> voClass, Object params, QueryType queryType) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.query(params, queryType);
	}
	
	public Page doQuery(Page page,String sql,Class<?> voClass, final Object... values) throws Exception {
		HibernateDAO  dao = DAOFactory.getInstance().createHibernateDAO();
        return dao.findPageBySql(page,sql,voClass,values);
	}
	
	/**
	 * ======================================================================
	 * 以下方法为带日志记录日志方法
	 * ======================================================================
	 */
	public Object doCreate(Class<?> voClass, Object vo, Class<?> logClass, Object logVO) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		HibernateDAO logdao = DAOFactory.getInstance().createHibernateDAO(logClass);
		logdao.save(logVO);
		return dao.save(vo);
	}

	public void doRemoveByVO(Class<?> voClass, Object vo, Class<?> logClass, Object logVO) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		HibernateDAO logdao = DAOFactory.getInstance().createHibernateDAO(logClass);
		logdao.save(logVO);
		dao.deleteByVO(vo);
	}

	public void doRemoveByPK(Class<?> voClass, Serializable pk, Class<?> logClass, Object logVO) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		HibernateDAO logdao = DAOFactory.getInstance().createHibernateDAO(logClass);
		logdao.save(logVO);
		dao.deleteByPK(pk);
	}

	/**
	 * 带日志更新
	 * @param voClass
	 * @param vo
	 * @param logClass
	 * @param logVO
	 * @return
	 * @throws Exception
	 */
	public Object doUpdate(Class<?> voClass, Object vo, Class<?> logClass, Object logVO) throws Exception {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		HibernateDAO logdao = DAOFactory.getInstance().createHibernateDAO(logClass);
		logdao.save(logVO);
		return dao.saveOrUpdate(vo);
	}

	/**
	 * 查询接口封装
	 * @param strategy
	 * @return
	 * @throws Exception
	 */
	public Object doProcess(Strategy strategy) throws Exception {
		return strategy.process();
	}
	
	/**
	 * 模型查找,需要注意此方法不能应用于主键
	 * @param voClass
	 * @param entity
	 * @return
	 */
	public List<?> doFindByExampleVO(Class<?> voClass, Object entity){
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.findByExample(entity);
	}
	/**
	 * 属性值记录查询
	 * @param voClass
	 * @param propertyName
	 * @param propertyValue
	 * @return
	 */
	public List<?> doFindByProperty(Class<?> voClass, String propertyName, Object propertyValue){
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.findByProperty(propertyName, propertyValue);
	}
	
	/**
	 * 查找属性最大值
	 * @param voClass
	 * @param propertyName
	 * @return
	 * @throws Exception
	 */
	public Object doFindMaxPropertyValle(Class<?> voClass, String propertyName){
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(voClass);
		return dao.getMaxValue(propertyName);
	}
	
	public List<?> doFindByHQL(final String hql, final Object... values){
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.findByHQL(hql, values);
	}
	
	public List doFindBySQL(final String sql , final Map<String, Type> scalars , final Object... values){
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.findBySQL(sql, scalars, values);
	}
	public List doFindByAliasSql(final String sql, Class<?> voClass, final Object... values) {
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.findByAliasSql(sql, voClass, values);
	}
	
	
	public Object findUniqueByHQL(final String hql, final Object... values){
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.findUniqueByHQL(hql, values);
	}
	
	public List<?> findByHQL(final String hql, final Map<String, Object> params){
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.findByHQL(hql, params);
	}
	
	public Object findUniqueByHQL(final String hql, final Map<String, Object> params){
		HibernateDAO dao = DAOFactory.getInstance().createHibernateDAO(Object.class);
		return dao.findUniqueByHQL(hql, params);
	}
	

	/**
	 * 创建LogVO实体对象，子类可以重载该方法。
	 * @param userid 操作员工号
	 * @param accesstime 操作开始时间
	 * @param oprType 操作类型，默认是表对象名字
	 * @param action  操作类型，值可从类OperAction获得，如插入：OperAction.INSERT
	 * @param ip   操作IP
	 * @param oldVO 操作前对象值
	 * @param newVO 操作完毕后的对象值
	 * @param state 状态，值可从类OperState获得，如成功：OperState.SUCCESS
	 * @return
	 * @throws Exception
	 */
	public LogAccessVO createAccesslogVO(String userid, Date accesstime,String oprType,String action,String ip,Object oldVO,Object newVO,Long state) throws Exception {
		LogAccessVO vo = new LogAccessVO();
		String cost =  (System.currentTimeMillis() - accesstime.getTime())/1000+"";
		vo.setLogid(Sequence.getSequence());
		vo.setAccesstime(accesstime);
		vo.setCmd(action);//新增、修改、删除
		vo.setCost(Integer.valueOf(cost));
		vo.setDescription(state+"");//描述：状态（成功 or 失败）
		vo.setIp(ip);
		String param = "";
		if(OperAction.UPDATE.equals(action)){
			String oldObject = oldVO == null ? "" : ReflectionToStringBuilder.toString(oldVO, ManageLogToStringStyle.MANAGE_LOG_STYLE);
			String newObject = newVO == null ? "" : ReflectionToStringBuilder.toString(newVO, ManageLogToStringStyle.MANAGE_LOG_STYLE);
			param += "修改对象.修改前:"+oldObject+"\n"+"修改后："+newObject;
		}else if(OperAction.INSERT.equals(action)){
			String newObject = newVO == null ? "" : ReflectionToStringBuilder.toString(newVO, ManageLogToStringStyle.MANAGE_LOG_STYLE);
			param += "新增对象:"+newObject;
		}else if(OperAction.DELETE.equals(action)){
			String oldObject = oldVO == null ? "" : ReflectionToStringBuilder.toString(oldVO, ManageLogToStringStyle.MANAGE_LOG_STYLE);
			param += "删除对象:"+oldObject;
		}
		vo.setParam(param);
		vo.setUserid(userid);
		return vo;
	}
	
	
}
